1 module hip.systems.gamepads.xbox; 2 import hip.util.system; 3 import hip.systems.gamepad; 4 5 ///Refer to https://docs.microsoft.com/en-us/uwp/api/windows.gaming.input.gamepadbuttons?view=winrt-20348 6 enum HipXboxGamepadButton : int 7 { 8 none = 0, ///No button. 9 menu = 1, ///Menu button. 10 view = 1<<1, ///View button. 11 a = 1<<2, ///A button. 12 b = 1<<3, ///B button. 13 x = 1<<4, ///X button. 14 y = 1<<5, ///Y button. 15 dPadUp = 1<<6, ///D-pad up. 16 dPadDown = 1<<7, ///D-pad down. 17 dPadLeft = 1<<8, ///D-pad left. 18 dPadRight = 1<<9, ///D-pad right. 19 leftShoulder = 1<<10, ///Left bumper. 20 rightShoulder = 1<<11, ///Right bumper. 21 leftThumbstick = 1<<12, ///Left stick. 22 rightThumbstick = 1<<13, ///Right stick. 23 paddle1 = 1<<14, ///The first paddle. 24 paddle2 = 1<<15, ///The second paddle. 25 paddle3 = 1<<16, ///The third paddle. 26 paddle4 = 1<<17, ///The fourth paddle. 27 } 28 29 30 pragma(inline, true) 31 bool isXboxGamepadButtonPressed(int gamepadState, HipXboxGamepadButton btn){return (gamepadState & btn) == btn;} 32 33 struct HipInputXboxGamepadState 34 { 35 int buttons; 36 double leftAnalogX; 37 double leftAnalogY; 38 double rightAnalogX; 39 double rightAnalogY; 40 double leftTrigger; 41 double rightTrigger; 42 } 43 44 45 //////// External API //////// 46 47 extern(System) __gshared 48 { 49 ubyte* function() HipGamepadCheckConnectedGamepads; 50 HipGamepadBatteryStatus function(ubyte id) HipGamepadGetBatteryStatus; 51 HipInputXboxGamepadState function(ubyte id) HipGamepadGetXboxGamepadState; 52 bool function(ubyte id) HipGamepadIsWireless; 53 ubyte function() HipGamepadQueryConnectedGamepadsCount; 54 55 void function( 56 ubyte id, 57 double leftMotor, 58 double rightMotor, 59 double leftTrigger, 60 double rightTrigger 61 ) HipGamepadSetXboxGamepadVibration; 62 } 63 64 65 66 extern(D): 67 void initXboxGamepadInput() 68 { 69 __gshared bool hasInit = false; 70 if(hasInit) 71 return; 72 version(Windows) 73 { 74 string[] errors = dllImportVariables!( 75 HipGamepadCheckConnectedGamepads, 76 HipGamepadGetBatteryStatus, 77 HipGamepadGetXboxGamepadState, 78 HipGamepadIsWireless, 79 HipGamepadQueryConnectedGamepadsCount, 80 HipGamepadSetXboxGamepadVibration 81 ); 82 foreach(err; errors) 83 { 84 import hip.console.log; 85 logln("HIPREME_ENGINE: Could not load ", err); 86 } 87 } 88 89 hasInit = true; 90 } 91 92 //////// End External API //////// 93 94 /** Engine task: 95 * Send gamepad connect and disconnect events 96 * Poll every connected gamepad every frame 97 * Should always return a neutral state for every disconnected gamepad 98 * 99 * Game task: 100 * Check gamepad count 101 * Decide what will do with connected gamepads 102 */ 103 class HipXBOXGamepad : IHipGamepadImpl 104 { 105 void poll(HipGamepad pad) 106 { 107 HipInputXboxGamepadState state = HipGamepadGetXboxGamepadState(pad.getId); 108 int b = state.buttons; 109 with(pad) 110 { 111 setAnalog(HipGamepadAnalogs.leftStick, [state.leftAnalogX, state.leftAnalogY, 1]); 112 setAnalog(HipGamepadAnalogs.rightStick, [state.rightAnalogX, state.rightAnalogY, 1]); 113 114 leftTrigger = state.leftTrigger; 115 rightTrigger = state.rightTrigger; 116 setButtonPressed(HipGamepadButton.xboxY, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.y)); 117 setButtonPressed(HipGamepadButton.xboxX, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.x)); 118 setButtonPressed(HipGamepadButton.xboxA, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.a)); 119 setButtonPressed(HipGamepadButton.xboxB, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.b)); 120 121 setButtonPressed(HipGamepadButton.dPadUp, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadUp)); 122 setButtonPressed(HipGamepadButton.dPadLeft, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadLeft)); 123 setButtonPressed(HipGamepadButton.dPadDown, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadDown)); 124 setButtonPressed(HipGamepadButton.dPadRight, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadRight)); 125 126 setButtonPressed(HipGamepadButton.left1, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.leftShoulder)); 127 setButtonPressed(HipGamepadButton.right1, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.rightShoulder)); 128 // setButtonPressed(HipGamepadButton.left2, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.pa)); 129 // setButtonPressed(HipGamepadButton.right2, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.dPadRight)); 130 131 setButtonPressed(HipGamepadButton.left3, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.leftThumbstick)); 132 setButtonPressed(HipGamepadButton.right3, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.rightThumbstick)); 133 134 setButtonPressed(HipGamepadButton.start, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.menu)); 135 setButtonPressed(HipGamepadButton.select, isXboxGamepadButtonPressed(b, HipXboxGamepadButton.view)); 136 } 137 } 138 139 void setVibrating(ubyte id, double leftMotor, double rightMotor, double leftTrigger, double rightTrigger) 140 { 141 HipGamepadSetXboxGamepadVibration(id, 142 leftMotor, 143 rightMotor, 144 leftTrigger, 145 rightTrigger 146 ); 147 } 148 bool isWireless(ubyte id){return HipGamepadIsWireless(id);} 149 HipGamepadBatteryStatus getBatteryStatus(ubyte id){return HipGamepadGetBatteryStatus(id);} 150 }